package ltd.newbee.mall.config;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import ltd.newbee.mall.entity.AdminUser;
import ltd.newbee.mall.service.AdminUserService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;

/**
 * @description:
 * @author: qzx
 * @date: 2022-08-12 16:46
 * @version: 1.0
 */
@Configuration
@ConfigurationProperties(prefix = "socketio")
@Data
@Slf4j
public class SocketIOConfig {

    private String host;

    private Integer port;

    private int bossCount;

    private int workCount;

    private boolean allowCustomRequests;

    private int upgradeTimeout;

    private int pingTimeout;

    private int pingInterval;

    private String context;

    private String origin;

    @Resource
    @Lazy
    private AdminUserService adminUserService;

    @Bean
    public SocketIOServer socketIOServer() {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setSocketConfig(socketConfig);
        config.setHostname(host);
        config.setPort(port);
        config.setBossThreads(bossCount);
        config.setWorkerThreads(workCount);
        config.setAllowCustomRequests(allowCustomRequests);
        config.setUpgradeTimeout(upgradeTimeout);
        config.setPingTimeout(pingTimeout);
        config.setPingInterval(pingInterval);
        config.setOrigin(origin);
        config.setContext(context);
        config.setRandomSession(true);
        config.setAuthorizationListener(data -> {
            String accessToken = data.getSingleUrlParam("token");
            log.info("链接用户 accessToken = {} \n data = {} ", accessToken, JSONObject.toJSONString(data));
            if (StrUtil.isEmpty(accessToken)) {
                return false;
            }
            AdminUser user = adminUserService.selectByToken(accessToken);
            log.info("当前链接用户 user = {}", user);
            // return ObjectUtil.isEmpty(user);
            return true;
        });
        SocketIOServer socketIOServer = new SocketIOServer(config);
        socketIOServer.addNamespace("/");
        return socketIOServer;
    }

    /**
     * 用于扫描 netty-socketio 注解 比如 @OnConnect、@OnEvent
     */
    @Bean
    @ConditionalOnBean(value = {SocketIOServer.class})
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketIOServer) {
        return new SpringAnnotationScanner(socketIOServer);
    }
}
